# coding=utf-8
# zengyiqi

# 主页视图，主页各分页具体

import os
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from tkinter import *
from Dao.main import *
import datetime
import numpy as np
import matplotlib.pyplot as plt
from utils.rate import *
import webbrowser
from decimal import *


# 记账 功能实现
class InsertFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.time = tk.StringVar()
        self.gos = tk.StringVar()
        self.type = tk.StringVar()
        self.money = tk.StringVar()
        self.note = tk.StringVar()
        self.insert_page()

    def insert_page(self):
        timeNow = datetime.datetime.now()
        self.time.set(timeNow.strftime('%Y-%m-%d %H:%M:%S'))
        Label(self, text='').grid(row=0, column=1, padx=10)
        tk.Label(self, text='日期：').grid(row=1, column=1, pady=10)
        ttk.Entry(self, textvariable=self.time).grid(row=1, column=2, pady=10)
        tk.Label(self, text='收入/支出：').grid(row=2, column=1, pady=10)
        self.combobox01 = ttk.Combobox(self, values=['支出', '收入'], state='readonly', textvariable=self.gos,
                                       width=18)
        self.combobox01.grid(row=2, column=2, pady=10)
        self.combobox01.current(0)

        tk.Label(self, text='消费项目：').grid(row=3, column=1, pady=10)
        self.combobox02 = ttk.Combobox(self, values=['', '餐饮', '购物', '娱乐', '交通', '学习', '其它'], state='readonly',
                                       textvariable=self.type, width=18)
        self.combobox02.grid(row=3, column=2, pady=10)
        self.combobox02.current(0)
        ttk.Label(self, text='金额：').grid(row=4, column=1, pady=10)
        ttk.Entry(self, textvariable=self.money).grid(row=4, column=2, pady=10)
        ttk.Label(self, text='备注：').grid(row=5, column=1, pady=10)
        ttk.Entry(self, textvariable=self.note).grid(row=5, column=2, pady=10)
        ttk.Button(self, text='记一笔', command=self.save_data).grid(row=6, column=2, pady=10)

    def save_data(self):
        # 当选择了收入，清空消费项目的值
        if self.gos.get() == '收入':
            self.type.set('')
        if self.gos.get() == "支出" and self.type.get() == '':
            self.type.set('其他')

        # 调用mainDao进行保存操作
        m = Main()
        m.save_data(self.time.get(), self.gos.get(), self.type.get(), self.money.get(), self.note.get())
        tk.messagebox.showinfo(message='记账成功')

        timeNow = datetime.datetime.now()
        # 重置输入框
        self.time.set(timeNow.strftime('%Y-%m-%d %H:%M:%S'))
        self.money.set('')
        self.note.set('')


# 按日期查找，删除，修改，刷新 功能实现
class SearchDayFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.account_query = []
        self.timeDay = tk.StringVar()
        self.time = tk.StringVar()
        self.gos = tk.StringVar()
        self.type = tk.StringVar()
        self.money = tk.StringVar()
        self.note = tk.StringVar()
        self.id_search()

    # 创建界面
    def id_search(self):
        timeNow = datetime.datetime.now()

        tk.Label(self, text='请输入日期(输入格式为2022-05-15)：').grid(row=0, column=0, pady=10, columnspan=2)
        self.entry01 = ttk.Entry(self, textvariable=self.timeDay)
        self.entry01.grid(row=0, column=2, pady=10, columnspan=2)
        self.timeDay.set(timeNow.strftime('%Y-%m-%d'))
        self.Button1 = ttk.Button(self, text='查询', command=self.get_account)
        self.Button1.grid(row=1, column=0, pady=10)
        self.Button2 = ttk.Button(self, text='修改', command=self.update_account)
        self.Button2.grid(row=1, column=1, pady=10)
        self.Button3 = ttk.Button(self, text='删除', command=self.delete_account)
        self.Button3.grid(row=1, column=2, pady=10)
        ttk.Button(self, text='刷新', command=self.show_account).grid(row=1, column=3, pady=10)
        self.show_account()

    # Treeview
    def show_account(self):
        self.table_view = tk.Frame()
        columns = ("time", "gos", "type", "money", "note")
        # selectmode="extended"可选中多个 "none"不可选中 "browse"一次只能选中一项
        self.tree_view = ttk.Treeview(self, show='headings', columns=columns, selectmode="browse")
        self.tree_view.column('time', width=130, anchor='center')
        self.tree_view.column('gos', width=80, anchor='center')
        self.tree_view.column('type', width=80, anchor='center')
        self.tree_view.column('money', width=80, anchor='center')
        self.tree_view.column('note', width=80, anchor='center')
        self.tree_view.heading('time', text='日期')
        self.tree_view.heading('gos', text='支出/收入')
        self.tree_view.heading('type', text='消费项目')
        self.tree_view.heading('money', text='金额')
        self.tree_view.heading('note', text='备注')
        self.tree_view.grid(row=2, column=0, columnspan=4)
        self.get_account_all()

    # Treeview找值、传值
    def get_account(self):
        # 清空Treeview
        for item in self.tree_view.get_children():
            self.tree_view.delete(item)

        m = Main()

        if self.timeDay.get() != "":
            # 调用mainDao进行查值操作
            self.account_query = []
            info = m.get_account_day(self.timeDay.get())
            self.account_query = info
        else:
            self.account_query = []
            info = m.get_account_all()
            self.account_query = info

        # 传值到Treeview
        index = 0
        for item in self.account_query:
            self.tree_view.insert('', index + 1, values=(
                item['time'], item['gos'], item['type'], item['money'], item['note']
            ))

    # 刷新显示所有值
    def get_account_all(self):
        m = Main()
        self.account_query = []
        info = m.get_account_all()
        self.account_query = info

        index = 0
        for item in self.account_query:
            self.tree_view.insert('', index + 1, values=(
                item['time'], item['gos'], item['type'], item['money'], item['note']
            ))

    # 修改功能 1、界面，取值
    def update_account(self):
        if not self.tree_view.selection():
            tk.messagebox.showwarning(message='请先选中数据，再进行修改！')
            return
        item = self.tree_view.selection()

        # 获取旧值
        self.time.set(self.tree_view.item(item, 'values')[0])
        # print(self.time.get())
        self.gos.set(self.tree_view.item(item, 'values')[1])
        self.type.set(self.tree_view.item(item, 'values')[2])
        self.money.set(self.tree_view.item(item, 'values')[3])
        self.note.set(self.tree_view.item(item, 'values')[4])

        # Toplevel()创建顶级窗口
        self.edit_win = Toplevel()
        width = 300
        height = 350
        self.edit_win.geometry(f'{width}x{height}')
        # 2、计算中心坐标点
        screen_width = self.edit_win.winfo_screenwidth() / 2 - width / 2
        screen_height = self.edit_win.winfo_screenheight() / 2 - height / 2
        # 移动到中心点
        self.edit_win.geometry(f"+{int(screen_width)}+{int(screen_height)}")
        self.edit_win.title = '修改信息'

        Label(self.edit_win, text='').grid(row=0, column=1, padx=10)

        tk.Label(self.edit_win, text='记账时间：').grid(row=1, column=1, pady=10, padx=25)
        ttk.Entry(self.edit_win, textvariable=self.time, state='readonly').grid(row=1, column=2, pady=10)

        tk.Label(self.edit_win, text='收入/支出：').grid(row=2, column=1, pady=10)
        self.combobox01 = ttk.Combobox(self.edit_win, values=['支出', '收入'], state='readonly', textvariable=self.gos,
                                       width=18)
        self.combobox01.grid(row=2, column=2, pady=10)

        tk.Label(self.edit_win, text='消费项目：').grid(row=3, column=1, pady=10)
        self.combobox02 = ttk.Combobox(self.edit_win, values=['', '餐饮', '购物', '娱乐', '交通', '学习', '其它'], state='readonly',
                                       textvariable=self.type, width=18)
        self.combobox02.grid(row=3, column=2, pady=10)

        ttk.Label(self.edit_win, text='金额：').grid(row=4, column=1, pady=10)
        ttk.Entry(self.edit_win, textvariable=self.money).grid(row=4, column=2, pady=10)
        ttk.Label(self.edit_win, text='备注：').grid(row=5, column=1, pady=10)
        ttk.Entry(self.edit_win, textvariable=self.note).grid(row=5, column=2, pady=10)

        ttk.Button(self.edit_win, text='修改', command=self.edit_account).grid(row=6, column=1, columnspan=2, pady=10)

        self.edit_win.mainloop()

    # 修改功能 2、该值
    def edit_account(self):
        if self.gos.get() == "收入":
            self.type.set('')
        if self.gos.get() == "支出" and self.type.get() == '':
            self.type.set('其他')
        m = Main()
        m.edit_account(self.time.get(), self.gos.get(), self.type.get(), self.money.get(), self.note.get())
        tk.messagebox.showinfo(message='修改成功')
        self.edit_win.destroy()

    # 删除功能
    def delete_account(self):
        if not self.tree_view.selection():
            tk.messagebox.showwarning(message='请先选中数据，再进行删除！')
            return
        item = self.tree_view.selection()
        time = self.tree_view.item(item, 'values')[0]
        # print(time)
        m = Main()
        m.delete_account(time)
        self.tree_view.delete(self.tree_view.selection())


# 按消费项目查找 功能实现
class SearchTypeFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.account_query = []
        self.type = tk.StringVar()
        self.id_search()

    def id_search(self):
        tk.Label(self, text='请选择消费类别：').grid(row=0, column=0, pady=10)
        self.combobox01 = ttk.Combobox(self, values=['餐饮', '购物', '娱乐', '交通', '学习', '其它', ''], state='readonly',
                                       textvariable=self.type, width=18)
        self.combobox01.grid(row=0, column=1, pady=10)
        self.combobox01.current(0)
        self.Button1 = ttk.Button(self, text='查询', command=self.get_account)
        self.Button1.grid(row=1, column=0, pady=10, columnspan=3)
        self.show_account()

    def show_account(self):
        self.table_view = tk.Frame()
        columns = ("time", "gos", "type", "money", "note")
        columns_value = ("id", "姓名", "语文", "数学", "英语")
        self.tree_view = ttk.Treeview(self, show='headings', columns=columns)
        self.tree_view.column('time', width=130, anchor='center')
        self.tree_view.column('gos', width=80, anchor='center')
        self.tree_view.column('type', width=80, anchor='center')
        self.tree_view.column('money', width=80, anchor='center')
        self.tree_view.column('note', width=80, anchor='center')
        self.tree_view.heading('time', text='日期')
        self.tree_view.heading('gos', text='支出/收入')
        self.tree_view.heading('type', text='消费项目')
        self.tree_view.heading('money', text='金额')
        self.tree_view.heading('note', text='备注')
        self.tree_view.grid(row=2, column=0, columnspan=3)

    def get_account(self):
        # 清空Treeview
        for item in self.tree_view.get_children():
            self.tree_view.delete(item)

        # 调用mainDao进行查值操作
        self.account_query = []
        m = Main()
        info = m.get_account_type(self.type.get())
        print(info)
        self.account_query = info

        # 传值到Treeview
        index = 0
        for item in self.account_query:
            self.tree_view.insert('', index + 1, values=(
                item['time'], item['gos'], item['type'], item['money'], item['note']
            ))


# 按支出/收入查找，金额统计 功能实现
class SearchGosFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.account_query = []
        self.gos = tk.StringVar()
        self.id_search()

    def id_search(self):
        tk.Label(self, text='请选择收入 or 支出：').grid(row=0, column=0, pady=10, columnspan=2)
        self.combobox01 = ttk.Combobox(self, values=['收入', '支出', '全部'], state='readonly', textvariable=self.gos,
                                       width=18)
        self.combobox01.grid(row=0, column=2, pady=10, columnspan=2)
        self.combobox01.current(0)
        self.Button1 = ttk.Button(self, text='查询', command=self.get_account)
        self.Button1.grid(row=1, column=0, pady=10, columnspan=2)
        self.label01 = tk.Label(self, font=('', 12))
        self.label01.grid(row=1, column=2, pady=10, columnspan=2)
        self.label01["text"] = "金额统计"
        self.label01.config(fg="red")
        self.show_account()

    def show_account(self):
        self.table_view = tk.Frame()
        columns = ("time", "gos", "type", "money", "note")
        self.tree_view = ttk.Treeview(self, show='headings', columns=columns)
        self.tree_view.column('time', width=130, anchor='center')
        self.tree_view.column('gos', width=80, anchor='center')
        self.tree_view.column('type', width=80, anchor='center')
        self.tree_view.column('money', width=80, anchor='center')
        self.tree_view.column('note', width=80, anchor='center')
        self.tree_view.heading('time', text='日期')
        self.tree_view.heading('gos', text='支出/收入')
        self.tree_view.heading('type', text='消费项目')
        self.tree_view.heading('money', text='金额')
        self.tree_view.heading('note', text='备注')
        self.tree_view.grid(row=2, column=0, columnspan=4)

    def get_account(self):
        # 清空Treeview
        for item in self.tree_view.get_children():
            self.tree_view.delete(item)

        # 调用mainDao进行查值操作
        self.account_query = []
        m = Main()
        key = None
        if self.gos.get() != "全部":
            info = m.get_account_gos(self.gos.get())
        else:
            info = m.get_account_all()

        self.account_query = info

        # 传值到Treeview
        index = 0
        for item in self.account_query:
            self.tree_view.insert('', index + 1, values=(
                item['time'], item['gos'], item['type'], item['money'], item['note']
            ))

        sum = 0
        for item in self.account_query:
            sum += float(item["money"])

        # 处理精度丢失问题
        sum = Decimal(sum).quantize(Decimal('0.00'))
        print(sum)

        self.label01["text"] = self.gos.get() + "总计：" + str(sum) + "元"


class TotalFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.canyin_total = tk.StringVar()
        self.gouwu_total = tk.StringVar()
        self.yule_total = tk.StringVar()
        self.jiaotong_total = tk.StringVar()
        self.xuexi_total = tk.StringVar()
        self.qita_total = tk.StringVar()
        self.Total_show()

    def Total_show(self):
        info, self.canyin_total, self.gouwu_total, self.yule_total, self.jiaotong_total, self.xuexi_total, self.qita_total = Main.get_account_type_total(
            self)
        tk.Label(self).grid(row=0, column=0, pady=8)
        tk.Label(self, text="餐饮共计：{0}元".format(self.canyin_total)).grid(row=1, column=0, pady=10, padx=20)
        tk.Label(self, text="购物共计：{0}元".format(self.gouwu_total)).grid(row=1, column=1, pady=10, padx=20)
        tk.Label(self, text="娱乐共计：{0}元".format(self.yule_total)).grid(row=2, column=0, pady=10)
        tk.Label(self, text="交通共计：{0}元".format(self.jiaotong_total)).grid(row=2, column=1, pady=10)
        tk.Label(self, text="学习共计：{0}元".format(self.xuexi_total)).grid(row=3, column=0, pady=10)
        tk.Label(self, text="其它共计：{0}元".format(self.qita_total)).grid(row=3, column=1, pady=10)
        self.Button1 = ttk.Button(self, text='生成比例图', command=self.Total_page)
        self.Button1.grid(row=4, column=0, pady=50, columnspan=2)

    # 比例图窗体
    def Total_page(self):
        # 解决无法显示中文的问题
        plt.rcParams['font.sans-serif'] = ['SimHei']

        labels = ['餐饮', '购物', '娱乐', '交通', '学习', '其它']
        info, canyin_total, gouwu_total, yule_total, jiaotong_total, xuexi_total, qita_total = Main.get_account_type_total(
            self)
        # print(info)
        # print(canyin_total, gouwu_total, yule_total, jiaotong_total, xuexi_total, qita_total)

        value = list(map(float, info.split(',')))
        print(value)
        values = np.array(value)
        print(values)

        fig = plt.figure()
        sub = fig.add_subplot(111)
        sub.pie(values, labels=labels, labeldistance=1.1, startangle=90, explode=[0, 0, 0, 0, 0, 0], autopct='%.1f%%',
                pctdistance=0.6,
                textprops=dict(fontsize=12), radius=1.0)
        sub.legend()
        plt.legend(loc=1, bbox_to_anchor=(1.2, 1))

        fig.suptitle('支出比例饼图', fontsize=16)
        fig.tight_layout()
        plt.show()


class RateFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.o = StringVar()  # 欧元汇率
        self.y = StringVar()  # 英镑汇率
        self.m = StringVar()  # 美元汇率
        self.num = StringVar()
        self.type = StringVar()
        self.r = StringVar()  # 人民币
        self.show_Rate()

    def show_Rate(self):
        # 获取爬虫数据
        try:
            self.o, self.y, self.m = getRate()
            print(self.o, self.y, self.m)
        except:
            self.o = 7.1
            self.y = 8.3
            self.m = 6.6

        tk.Label(self).grid(row=0, column=0, pady=8)
        self.label01 = tk.Label(self, text="中国银行实时汇率", font=('', 13))
        self.label01.grid(row=1, column=0, pady=10, padx=5, columnspan=2)
        ttk.Button(self, text='前往查看', command=self.openXml).grid(row=1, column=2, pady=10)
        tk.Label(self, text="1欧元EUR={0}人民币CNY".format(self.o)).grid(row=2, column=0, pady=10, columnspan=3)
        tk.Label(self, text="1英镑GBP={0}人民币CNY".format(self.y)).grid(row=3, column=0, pady=10, columnspan=3)
        tk.Label(self, text="1美元USD={0}人民币CNY".format(self.m)).grid(row=4, column=0, pady=10, columnspan=3)

        ttk.Entry(self, textvariable=self.num, width=10).grid(row=5, column=0, pady=10)
        self.num.set(1)
        self.combobox01 = ttk.Combobox(self, values=['EUR', 'GBP', 'USD'], state='readonly', textvariable=self.type,
                                       width=10)
        self.combobox01.grid(row=5, column=1, pady=10, padx=3)
        self.combobox01.current(0)
        tk.Label(self, textvariable=self.r, font=('', 12)).grid(row=5, column=2, pady=10)
        self.r.set(" =        人民币")
        ttk.Button(self, text='转换', command=self.getCNY).grid(row=6, column=0, pady=10, columnspan=3)

    # 打开网站
    def openXml(self):
        url = 'www.boc.cn/sourcedb/whpj/'
        webbrowser.open(url)

    # 汇率计算
    def getCNY(self):
        t = self.type.get()
        if t == 'EUR':
            cny = eval(self.num.get()) * self.o
            print(cny)
            cny = " = " + str(cny) + " 人民币"
            # print(cny)
            self.r.set(cny)
        elif t == 'GBP':
            cny = eval(self.num.get()) * self.y
            cny = " = " + str(cny) + " 人民币"
            self.r.set(cny)
        elif t == 'USD':
            cny = eval(self.num.get()) * self.m
            cny = " = " + str(cny) + " 人民币"
            self.r.set(cny)


class AboutFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.label01 = tk.Label(self, text='感谢您使用个人记账系统！', font=('', 20))
        self.label01.grid(row=0, column=0, pady=10)
        self.label01.config(fg="red")
        self.label02 = tk.Label(self,
                                text='    本系统使用了tkinter,tkinter.tkk,ttkbootstrap,matplotlib,爬虫等技术，采用前后端代码分离的方式开发.实现了记账，按日期查找账目(修改账目，删除账目)，按支出/收入查找账目，按消费项目查找账目，统计（制作比例图），显示实时汇率，汇率换算等功能。',
                                wraplength=580, font=('', 13), anchor='w', justify='left')
        self.label02.grid(row=1, column=0, pady=10)
        tk.Label(self, text='').grid(row=2, column=0, pady=10)
